package com.bbz.effectivejava.chapter1.buildobject;

/**
 * 本样例是对象Build模式，能保证重叠构造器模式的安全性，又能保证JavaBeans模式那么好的可读性
 *
 * 重叠构造器模式是安全，但是每个参数都需要传递，对于可选参数构建时，很不方便
 * JavaBeans模式，通过set为对象赋值，可读性高，但是针对于多线程构建Bean时，线程不安全。
 * @author Zhang
 *
 */
public class BuildDemo {
	private final int servingSize;
	private final int servings;
	private final int calories;
	private final int fat;
	
	public static class Builder{
		//必需的参数
		private final int servingSize;
		private final int servings;
		//可选参数 是动态构建的，所以在Builder中不要声明为final
		private  int calories;
		private  int fat;
		public Builder(int servingSize,int servings) {
			this.servingSize=servingSize;
			this.servings=servings;
		}
		public Builder calories(int val) {
			calories=val;
			return this;
		}
		public Builder fat(int val) {
			fat=val;
			return this;
		}
		public BuildDemo build() {
			return new BuildDemo(this);
		}
	}
	
	public BuildDemo(Builder builder) {
		servingSize=builder.servingSize;
		servings=builder.servings;
		calories=builder.calories;
		fat=builder.fat;
	}
	@Override
	public String toString() {
		return String.format("servingSize:%d,servings:%d,calories:%d,fat:%d", servingSize,servings,calories,fat);
	}
	
	
	/**
	 * 客戶端初始化构建BuildDemo实例
	 * @param args
	 */
	public static void main(String args[]) {
		BuildDemo buildDemo=new BuildDemo.Builder(240,8).calories(10).fat(1).build();
		System.out.println(buildDemo);
		BuildDemo buildDemo1=new BuildDemo.Builder(240,8).calories(10).fat(2).build();
		System.out.println(buildDemo1); 
	}
}
